package com.qianfeng.android.baoman.util;

import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.AsyncTask;
import android.widget.ImageView;

/**
 * Created by maxiaoyu on 2015/2/6.
 * User:Maxiaoyu
 * Date:2015/2/6
 * Email:731436452@qq.com
 */

/**
 * 通用的图片下载异步任务，通过构造方法设置需要设置图片的ImageView
 */
public class ImageLoader extends AsyncTask<String, Integer, byte[]> {
    //设置成员变量，用于引用外部的ImageView
    private ImageView myImageView;
    private String imageUrl;
    private int reqWidth;
    private int reqHeight;

    public ImageLoader(ImageView myImageView) {
        this.myImageView = myImageView;

    }

    @Override
    protected byte[] doInBackground(String... params) {
        byte[] ret = new byte[0];
        if (params != null && params.length > 0) {
            if (params.length == 3) {
                reqWidth = Integer.parseInt(params[1]);
                reqHeight = Integer.parseInt(params[2]);
            }
            imageUrl = params[0];
            ret = HttpTool.get(imageUrl);
        }
        return ret;
    }


    @Override
    protected void onPostExecute(byte[] bytes) {
        if (bytes != null) {
            //TODO 更新文件缓存
            FileCache fileCache = FileCache.getInstance();
            fileCache.putContent(imageUrl, bytes);
//            Bitmap bitmap = BitmapFactory.decodeByteArray(bytes, 0, bytes.length);
            Bitmap bitmap=null;
            if (reqWidth != 0 && reqHeight != 0) {
                //进行图片的二次采集
                bitmap = getSampleImage(bytes, reqWidth, reqHeight);
            }
            //TODO　更新内存缓存
            ImageCache imageCache = ImageCache.getInstance();
            //向内存中设置图片缓存
            imageCache.putImage(imageUrl, bitmap);
            if (myImageView != null) {
                Object tag = myImageView.getTag();
                if (tag != null) {
                    //TODO  检查Tag与下载地址是否相同
                    if (tag instanceof String) {
                        String sTag = (String) tag;
                        if (sTag.equals(imageUrl)) {

                            myImageView.setImageBitmap(bitmap);
                        }
                    }
                } else {
                    myImageView.setImageBitmap(bitmap);
                }
            }
        }
    }

    //进行图片的二次采样
    public Bitmap getSampleImage(byte[] buf,int reqWidth, int reqHeight) {
        //TODO 利用图片二次采样进行内存占用的减少
        Bitmap bitmap = null;
        // 按照图片原始大小进行解码  尺寸不会进行缩放，就是实际图片的内容
//                    bitmap = BitmapFactory.decodeByteArray(buf, 0, buf.length);
        //根据指定的图片解码的参数，进行图片的解码
        BitmapFactory.Options opts = new BitmapFactory.Options();
        //解码参数
        opts.inPurgeable = true;// 解码之后的图片是否可以被清除
        //是否只进行图片尺寸的解码，而不进行真实图片的解码
        //！！！！！！！也就是BitmapFactory.decodeXXXX 方法将不会返回Bitmap ,实际数据
        //            能在解码之后，更新Options当中的图片 宽度，高度，两个信息。
        opts.inJustDecodeBounds = true;
        bitmap = BitmapFactory.decodeByteArray(buf, 0, buf.length, opts);

        //开始第二次图片解码
        //   假设缩放后图片大小100*120*4
        //1 第二次采样需要禁用 inJustDecodeBounds ,设置为false
        opts.inJustDecodeBounds = false;
        //2 计算图片缩放比例,
        // 整数，这个整数需要计算出来
        // 代表， 解码出来的图片是原始图片每条边尺寸的1/n
        // 那么最终生成图片的面试时原始图片面积的1/(n*n);
        // n 就是isSampleSize 的数值，这个数值不能小于1.
        opts.inSampleSize = calculateInSampleSize(opts, reqWidth, reqHeight);
        bitmap = BitmapFactory.decodeByteArray(buf, 0, buf.length, opts);
        return bitmap;
    }


    /**
     * 计算图片采样率
     *
     * @param reqWidth  缩放宽度
     * @param reqHeight 缩放高度
     * @return
     */
    public static int calculateInSampleSize(
            BitmapFactory.Options options, int reqWidth, int reqHeight) {
        // Raw height and width of image
        final int height = options.outHeight;
        final int width = options.outWidth;
        int inSampleSize = 1;

        if (height > reqHeight || width > reqWidth) {

            final int halfHeight = height / 2;
            final int halfWidth = width / 2;

            // Calculate the largest inSampleSize value that is a power of 2 and keeps both
            // height and width larger than the requested height and width.
            while ((halfHeight / inSampleSize) > reqHeight
                    && (halfWidth / inSampleSize) > reqWidth) {
                inSampleSize *= 2;
            }
        }
        return inSampleSize;
    }
}
